﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.Framework.Common;

using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using MySCM.Common.Log;
using System.DirectoryServices;
using System.Net;
using System.Windows.Forms; // for MessageBox

namespace MySCM.Agent.TFS
{
    public class TfsCredential
    {
        public string domain;
        public string login;
        public string password;

        public TfsCredential()
        {
            domain = "%%CredentialDomain";
            login = "%%CredentialLogin";
            password = "%%CredentialPassword";
        }
    }


    public class TFSAgent
    {
        public Boolean PopMessageBox;
        public Boolean WriteLogFile;

        private NetworkCredential tfsCredential = new NetworkCredential("%%login", "%%password", "%%domain");
        private TfsTeamProjectCollection tpc;
        public string emailList = "";

        public TFSAgent()
        {
            tfsCredential = new NetworkCredential("%%login", "%%password", "%%domain");
            PopMessageBox = true;
            WriteLogFile = true;
        }

        public TFSAgent(string login, string passwd, string domain)
        {
            tfsCredential = new NetworkCredential(login, passwd, domain);
            PopMessageBox = false;
            WriteLogFile = true;
        }        
    

        public Boolean ExternalWorkitemExists(string TfsServerCollection, string projectName, string workitemType, int workitemId)
        {
            try
            {
                try
                {
                    TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri(TfsServerCollection), tfsCredential);
                    try
                    {
                        WorkItemStore workItemStore = tpc.GetService<WorkItemStore>();
                        try
                        {
                            string wiqlQuery = "Select ID, Title from WorkItems where ([Work Item Type] = 'External Workitem' and [External Work Item ID] = '" + workitemId.ToString() + "')";
                            WorkItemCollection witCollection = workItemStore.Query(wiqlQuery);
                            try
                            {
                                switch (witCollection.Count)
                                {
                                    case 0:
                                        return false;
                                    case 1:
                                        if (PopMessageBox)
                                            MessageBox.Show("Found one External Work Item - " + witCollection[0].Fields["External Work Item ID"].Value);
                                        return true;
                                    default:
                                        if (PopMessageBox)
                                            MessageBox.Show("More than one External Work Item was found, please contact your administrator to check data integrity");

                                        if (WriteLogFile)
                                            StaticLogger.WriteLog("Design", "Warning", "More than one External Work Item was found, please contact your administrator to check data integrity");
                                        return true;
                                }
                            }
                            catch (Exception e)
                            {
                                if (PopMessageBox)
                                    MessageBox.Show("EXCEPTION-ExternalWorkitemExists-WorkItemCollection.Count: " + e.Message);
                                if (WriteLogFile)
                                    StaticLogger.WriteLog("Design", "Fatal", "EXCEPTION-ExternalWorkitemExists-WorkItemCollection.Count: " + e.Message);
                            }
                        }
                        catch (Exception e)
                        {
                            if (PopMessageBox)
                                MessageBox.Show("EXCEPTION-ExternalWorkitemExists-WorkItemCollection: " + e.Message);
                            if (WriteLogFile)
                                StaticLogger.WriteLog("Design", "Fatal", "EXCEPTION-ExternalWorkitemExists-WorkItemCollection: " + e.Message);
                        }
                    }
                    catch (Exception e)
                    {
                        if (PopMessageBox)
                            MessageBox.Show("EXCEPTION-ExternalWorkitemExists-WorkItemStore: " + e.Message);
                        if (WriteLogFile)
                            StaticLogger.WriteLog("Design", "Fatal", "EXCEPTION-ExternalWorkitemExists-WorkItemStore: " + e.Message);
                    }
                }
                catch (Exception e)
                {
                    if (PopMessageBox)
                        MessageBox.Show("EXCEPTION-ExternalWorkitemExists-TfsTeamProjectCollection: " + e.Message);
                    if (WriteLogFile)
                        StaticLogger.WriteLog("Design", "Fatal", "EXCEPTION-ExternalWorkitemExists-TfsTeamProjectCollection: " + e.Message);
                }
            }
            catch (Exception e)
            {
                if (PopMessageBox)
                    MessageBox.Show("EXCEPTION-ExternalWorkitemExists: " + e.Message + "\nTfsServerCollection:" + TfsServerCollection + "\nprojectName" + projectName + "\nworkitemType:" + workitemType + "\nworkitemId:" + workitemId);
                if (WriteLogFile)
                    StaticLogger.WriteLog("Design", "Fatal", "EXCEPTION-ExternalWorkitemExists: " + e.Message + "\nTfsServerCollection:" + TfsServerCollection + "\nprojectName" + projectName + "\nworkitemType:" + workitemType + "\nworkitemId:" + workitemId);
                return true;
            }
            return true;
        }


        public string CreateExternalWorkitem(string TfsServerCollection, string projectName, string workitemType, int externalWorkitemId, string fieldString)
        {
            string returnString = "";
            try
            {
                if (PopMessageBox)
                    MessageBox.Show("CreateExternalWorkitem: " + TfsServerCollection + "-" + projectName + "-" + workitemType + "-" + externalWorkitemId.ToString() + "-" + fieldString);

                tpc = new TfsTeamProjectCollection(new Uri(TfsServerCollection), tfsCredential);
                WorkItemStore workItemStore = tpc.GetService<WorkItemStore>();

                Project tfsProject = workItemStore.Projects[projectName];
                WorkItemType wiType = tfsProject.WorkItemTypes[workitemType];
                WorkItem workitem = new WorkItem(wiType);
                WorkItemStore ws = new WorkItemStore(tpc);
                tpc.EnsureAuthenticated();
                IIdentityManagementService ims = tpc.GetService<IIdentityManagementService>();

                string fieldName = "";
                string fieldValue = "";
                foreach (string fd in fieldString.Split(';'))
                {
                    fieldName = fd.Split('=')[0];
                    fieldValue = fd.Split('=')[1];
                    foreach (Field f in workitem.Fields)
                    {
                        if (f.Name == fieldName)
                        {
                            if (f.Name == "Assigned To")
                            {
                                TeamFoundationIdentity identity = ims.ReadIdentity(IdentitySearchFactor.AccountName, fieldValue, MembershipQuery.None, ReadIdentityOptions.None);
                                if (identity == null)
                                    f.Value = "";
                                else
                                    f.Value = identity.DisplayName;
                            }
                            else
                            {
                                f.Value = fieldValue;
                            }
                        }
                    }
                }
                workitem.Save();
                returnString = "Workitem id:" + workitem.Id.ToString() + " has been created successfully for " + externalWorkitemId;
            }
            catch (Exception e)
            {
                if (PopMessageBox)
                    returnString = externalWorkitemId + " - EXCPTION-CreateExternalWorkitem:" + e.Message;
                    MessageBox.Show(returnString);
                return returnString;
            }
            return returnString;
        }


        public string UpdateExternalWorkitem(string TfsServerCollection, string projectName, string workitemType, int externalWorkitemId, string fieldString)
        {
            string returnString = "";
            string id = "Unknown Workitem ID";
            string changedFields = "";

            try
            {
                if (PopMessageBox)
                    MessageBox.Show("UpdateExternalWorkitem: " + TfsServerCollection + "-" + projectName + "-" + workitemType + "-" + externalWorkitemId.ToString() + "-" + fieldString);
                TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri(TfsServerCollection), tfsCredential);
                WorkItemStore workItemStore = tpc.GetService<WorkItemStore>();
                Project tfsProject = workItemStore.Projects[projectName];
                WorkItemType wiType = tfsProject.WorkItemTypes[workitemType];

                string wiqlQuery = "Select ID, Title from WorkItems where ([Work Item Type] = 'External Workitem' and [External Work Item ID] = '" + externalWorkitemId.ToString() + "')";
                WorkItemCollection witCollection = workItemStore.Query(wiqlQuery);
                if (witCollection.Count == 1)
                {

                    tpc.EnsureAuthenticated();
                    IIdentityManagementService ims = tpc.GetService<IIdentityManagementService>();
                    WorkItem workitem = witCollection[0];
                    workitem.Open();
                    id = workitem.Id.ToString();

                    string fieldName = "";
                    string fieldValue = "";
                    foreach (string fd in fieldString.Split(';'))
                    {
                        fieldName = fd.Split('=')[0];
                        fieldValue = fd.Split('=')[1];
                        foreach (Field f in workitem.Fields)
                        {
                            if (f.Name == fieldName)
                            {
                                string oldValue = f.Value.ToString();
                                if (f.Name == "Assigned To")
                                {
                                    TeamFoundationIdentity identity = ims.ReadIdentity(IdentitySearchFactor.AccountName, fieldValue, MembershipQuery.None, ReadIdentityOptions.None);
                                    if (identity == null)
                                        f.Value = "";
                                    else
                                        f.Value = identity.DisplayName;
                                }
                                else
                                {
                                    f.Value = fieldValue;
                                }
                                if (f.Value.ToString().ToLower() != oldValue.ToLower())
                                {
                                    if (changedFields == "")
                                        changedFields = f.Name;
                                    else
                                        changedFields = changedFields + ", " + f.Name;
                                }
                            }
                        }
                    }
                    if (changedFields != "")
                    {
                        workitem.Save();
                        returnString = workitem.Id.ToString() + " has been updated successfully for " + externalWorkitemId.ToString() + " - Changed fields: " + changedFields;
                    }
                    else
                        returnString = workitem.Id.ToString() + " has not been changed for " + externalWorkitemId.ToString();
                }
            }
            catch (Exception e)
            {
                returnString = id + "-" + externalWorkitemId.ToString() + " - EXCPTION-UpdateExternalWorkitem:" + e.Message;
                if (PopMessageBox)
                    MessageBox.Show(returnString);
                return returnString;
            }
            return returnString;
        }

    } // Class
} // Namespace
